package com.bitoon.basketdudes.web.admin;

import com.bitoon.basketdudes.web.BaseAction;
import com.bitoon.basketdudes.web.jpa.AdmRolSeccion;
import com.bitoon.basketdudes.web.jpa.PersistenceManager;
import com.bitoon.basketdudes.web.jpa.AdmUsuario;

import com.opensymphony.xwork2.*;
import com.opensymphony.xwork2.interceptor.Interceptor;
import java.util.*;
import javax.persistence.*;
import org.apache.log4j.Logger;

public class LoginInterceptor implements Interceptor {

    private Logger log = Logger.getLogger(LoginInterceptor.class);

    @Override
    public void destroy() {
    }

    @Override
    public void init() {
    }
    
    @Override
    public String intercept(ActionInvocation actionInvocation) throws Exception {

        Map session = ActionContext.getContext().getSession();
        String retorno = null;
        EntityManager em = null;

        try {

            EntityManagerFactory emfBasket = PersistenceManager.getInstance().getEntityManagerFactory(BaseAction.catalogos[1]);
            em = emfBasket.createEntityManager(); // checked

            //compruebo si el usuario está ya logado
            Boolean logado = estaLogado(session);

            if (logado){
                //obtengo el usuario que se ha interceptado
                AdmUsuario user = dameUsuarioLogado(session);

                // Fijar idioma
                String idioma = (String)session.get("bd_lang");
                if ( (idioma==null) || (!idioma.equalsIgnoreCase("en") && !idioma.equalsIgnoreCase("es"))) {
                    idioma = "en";
                }
                //log.debug("fijando idioma: " + idioma);
                ActionContext.getContext().setLocale(new Locale(idioma));

                //dependiendo del tipo de roles se le dejara ir a un sitio o a otro
                //(depende de la accion interceptada tambien¿?)
                String accion = ActionContext.getContext().getName();
                
                if(accion.compareTo("logout")!=0){
                    //si no es un logout
                    session.put("accion_redireccion", accion);

                    int seccion=0;
                    //si viene de una paginacion no hace falta saber si tiene permisos
                    if(accion.contains("xhr")==false){
                        seccion = dameSeccionAccion(accion);
                    }

                    if(accion.contains("xhr")==false && !tienePermisos(seccion,session)){
                        retorno = "no_autorizado";
                        log.debug("[interceptor] no usuario autorizado a ver una seccion");
                    }else{
                        //devuelvo el contexto a la accion que se ha interceptado
                        //porque está autorizado y tiene permisos
                        retorno = actionInvocation.invoke();
                        log.debug("[interceptor] usuario autorizado");
                    }
                }
                else{
                    //si es un logout devuelvo el contexto a la accion que se ha interceptado
                    retorno = actionInvocation.invoke();
                }
            } else{
                log.debug("[Interceptor] usuario no autorizado");
                retorno = "input";
            }

        } catch (Exception e) {
            log.error("Error", e);
        } finally {
            try { em.close(); } catch (Exception e) { }
        }
        return retorno;
    }

    private int dameSeccionAccion(String accion){
        //devuelve el ID de la seccion de la BD asociada a dicha accion
        log.debug("accion: "+accion);
        Breadcrumb b = new Breadcrumb(accion);
        b.getIdSeccion();
        return Integer.parseInt(b.getSeccion_navegacion());
    }

    private boolean tienePermisos(int seccion,Map session){

        List<AdmRolSeccion> permisos = (List<AdmRolSeccion>)session.get("admin_permisos");
        boolean autorizado = true; //por defecto esta autorizado

        log.debug("[tienePermisos] seccion: " + seccion);

        for(AdmRolSeccion rs : permisos){
            //si tiene permisos de lectura(minimo este) o escritura
            //log.debug("es seccion: " +(rs.getAdmSeccion().getId()==seccion) + " permisos: " + rs.getPermiso());
            if(rs.getAdmSeccion().getId()==seccion && rs.getPermiso()==0){
                autorizado=false;
            }
        }

        log.debug("[tienePermisos] autorizado: " + autorizado);

        return autorizado;
    }

    private boolean estaLogado(Map session) {
        //si existe la variable de sesion "btnadm_userAdminId"
        //devuelvo true logado sino false
        boolean retorno = false;

        if (session.containsKey("admin_userId")) {
            if( (Integer)session.get("admin_userId") > 0) {
                retorno = true;
            }
        }

        return retorno;
    }

    private AdmUsuario dameUsuarioLogado(Map session) {
        //devuelve el objeto de la sesion USUARIOADMIN
        AdmUsuario retorno = null;

        if (session.containsKey("admin_userLogado")) {
            retorno = (AdmUsuario)session.get("admin_userLogado");
        }
        return retorno;
    }

    private String dameIdUsuarioLogado(Map session) {
        String retorno = "";

        if (session.containsKey("admin_userId")) {
            retorno = (String)session.get("admin_userId");
        } else {
            retorno = "0";
        }

        return retorno;
    }

}